#pragma once

#include"Common.h"
#include"ThreadCache.h"
#include"PageCache.h"
#include"ObjectPool.h"
#include <assert.h>
static void* ConcurrentAlloc(size_t size)
{
    //获取内存大于256kb
    if(size>MAX_BYTES)
    { 
        //对齐，确认在哪个位置
        size_t alignSize = SizeClass::RoundUp(size);
        //确定需要多少页得span
        size_t kspan = alignSize >> PAGE_SHIFT;

        PageCache::GetInstance()->_pageMtx.lock();
        Span*span=PageCache::GetInstance()->NewSpan(kspan);
        span->objectsize = size;
        PageCache::GetInstance()->_pageMtx.unlock();
        //获取内存块地址
        void* ptr = (void*)(span->_pageId << PAGE_SHIFT);
        return ptr;
    }
    else
    {
        //通过TLS每个线程获取独属于自己的ThreadCache对象
        if (pTLSThreadCache == nullptr)
        {
            static ObjectPool<ThreadCache>tcpool;
            pTLSThreadCache = tcpool.New();
        }
        cout << std::this_thread::get_id() << ':' << pTLSThreadCache << endl;
        return pTLSThreadCache->Allocate(size);
    }
}

static void ConcurrentFree(void* ptr)
{
    Span* span = PageCache::GetInstance()->MapObjectTospan(ptr);
    size_t size = span->objectsize;
    if (size > MAX_BYTES)
    {
        
        PageCache::GetInstance()->_pageMtx.lock();
        PageCache::GetInstance()->ReleaseSpanToPagecache(span);
        PageCache::GetInstance()->_pageMtx.unlock();
    }
    else {
        assert(pTLSThreadCache);
        pTLSThreadCache->Deallocate(ptr, size);
    }
    
}